package com.jida.tijian.service;

import com.jida.tijian.dto.CalendarRequestDto;
import com.jida.tijian.dto.CalendarResponseDto;
import com.jida.tijian.dto.OrdersMapperDto;
import com.jida.tijian.mapper.HospitalMapper;
import com.jida.tijian.mapper.OrdersMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

//1.第一步 务必每次都要做的事情 加个帽子
@Service
public class CalendarServiceImpl implements CalendarService {
    //    需要对下列两个表进行sql操作
    @Autowired
    OrdersMapper ordersMapper;
    @Autowired
    HospitalMapper hospitalMapper;


    //业务层的内容 书写一个满足控制端需求的方法
    //    方法的返回 方法返回类型(返回list list中的元素是CalenderRequestDto类 里面的属性包含很多) 方法名（方法参数）
    @Override
    public List<CalendarResponseDto> listAppointmentCalendar(CalendarRequestDto calendarRequestDto) {
        //这个方法是 订单日期的list 四个字段：ymd total exist （total-exist）
        //前提参数 日期的年2025 月7
        //万年历                                             这是一个方法              参数1      年份：2025             参数2    7
        List<CalendarResponseDto> calendarResponseDtoList = getCurrentCalendarList(calendarRequestDto.getYear(), calendarRequestDto.getMonth());

        System.out.println("业务层（发现未来三十天 每个日期 中 存在的订单总数）：");
        //30天日历 调用
        List<CalendarResponseDto> calendarResponseDto30 = getCalendarList30(calendarRequestDto.getHpId());
        System.out.println("==============================================");

        // 遍历当月日历（12.1-12.31）
        for (int i = 0; i < calendarResponseDtoList.size(); i++) {
            //让cd 成为 calendarResponseDtoList下标为 i 的 item
            CalendarResponseDto cd = calendarResponseDtoList.get(i);//cd 只得是
            // 遍历未来30天预约数据（12.30-1.28）
            for (int j = 0; j < calendarResponseDto30.size(); j++) {
                CalendarResponseDto cdAppointment = calendarResponseDto30.get(j);
                // 检查非空并匹配日期
                if (cdAppointment != null && cdAppointment.getYmd() != null) {
                    if (cdAppointment.getYmd().equals(cd.getYmd())) {
                        cd.setTotal(cdAppointment.getTotal());
                        cd.setRemainder(cdAppointment.getRemainder());
                        cd.setExisting(cdAppointment.getExisting());
                    }
                }
            }

            //输出一下
//            System.out.println(calendarResponseDtoList.get(i).getTotal() + calendarResponseDtoList.get(i).getRemainder() + calendarResponseDtoList.get(i).getExisting());
        }
        for (int i = 0; i < calendarResponseDtoList.size(); i++) {
            System.out.println(calendarResponseDtoList.get(i).getYmd() + "  " + calendarResponseDtoList.get(i).getExisting()
                    + "  " + calendarResponseDtoList.get(i).getRemainder()
            );
        }
        return calendarResponseDtoList;
        //        return null;
    }

    //获取当前年和当前月的日历
    @Override
    public List<CalendarResponseDto> getCurrentCalendarList(Integer year, Integer month) {
        List<CalendarResponseDto> currentCalendar = new ArrayList<>();

        //做万年历
        boolean isRun = false;
        if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)) {
            isRun = true;
        }
        //计算从1900-01-01到现在的天数
        int totalDays = 0;
        for (int i = 1900; i < year; i++) {
            if ((i % 4 == 0 && i % 100 != 0) || (i % 400 == 0)) {
                totalDays += 366;
            } else {
                totalDays += 365;
            }
        }
        int beforeDays = 0;
        int currentDays = 0;
        for (int j = 1; j <= month; j++) {
            switch (j) {
                case 1:
                case 3:
                case 5:
                case 7:
                case 8:
                case 10:
                case 12:
                    currentDays = 31;
                    break;
                case 4:
                case 6:
                case 9:
                case 11:
                    currentDays = 30;
                    break;
                case 2:
                    if (isRun) {
                        currentDays = 29;
                    } else {
                        currentDays = 28;
                    }
                    break;
            }
            if (j < month) {
                beforeDays += currentDays;
            }
        }
        totalDays += beforeDays;
        int firstDayOfMonth = totalDays % 7 + 1;
        if (firstDayOfMonth == 7) {
            firstDayOfMonth = 0;
        }
        for (int k = 0; k < firstDayOfMonth; k++) {
            currentCalendar.add(new CalendarResponseDto());
        }
        for (int i = 1; i <= currentDays; i++) {
            String m = month < 10 ? "0" + month : month + "";
            String d = i < 10 ? "0" + i : i + "";
            currentCalendar.add(new CalendarResponseDto(year + "-" + m + "-" + d));
        }
        return currentCalendar;
    }

    @Override
    public List<CalendarResponseDto> getCalendarList30(Integer hpId) {
        //定义两个工具类
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar calendar = Calendar.getInstance();
        //做一个临时集合，作为去Orders表中查询的参数
        List<OrdersMapperDto> dtoList = new ArrayList<>();
        for (int i = 0; i < 30; i++) {  //就30天
            //创建OrdersMapperDto类 里面由两个属性
            OrdersMapperDto ordersMapperDto = new OrdersMapperDto();
            calendar.add(Calendar.DATE, 1);//调用add方法为 参数输入的日期 + 1
            //1. 调用 orderMapperDto的 setter方法 存储 日期 ##注！！该类的存储类型 是什么？String
            //2. 然而注意！calendar.getTime() 得到的是日期格式 不是 String类型
            //3. 所以调用 sdf 格式化
            ordersMapperDto.setDate(sdf.format(calendar.getTime()));  //2024-12-27
            //存储数据
            ordersMapperDto.setHpId(hpId);
            //为临时表添加 一条 ordersMapperDto 数据
            dtoList.add(ordersMapperDto);
        }
        //来，我们去数据库查询所选医院可以预约的30天然后每天的已经约号的数量（结果中有日期和已经约号数量）
        //现在要使用 数据库操作方法 listHospitalAppointmentNumber
        //1.去OrderMapper中 新增 一个sql方法
        //2.去Mapper对应的表中 新增方法的具体sql操作 记得id = 方法名 注意resultType 和 parameterType
        List<CalendarResponseDto> calendarResponseDtoList = ordersMapper.listHospitalAppointmentNumber(dtoList);
        for (int i = 0; i < calendarResponseDtoList.size(); i++) {
            System.out.println(calendarResponseDtoList.get(i).getYmd() + "  " + calendarResponseDtoList.get(i).getExisting());
        }
        //3.获取所选医院每天的约号最大数量 [0,200,200,200,200,200,200,100]
        String[] ruleArr = hospitalMapper.selectByPrimaryKey(hpId).getRule().split(",");//用逗号分隔

        //对前面的集合进行遍历，填充对象的另外两个数据：可以预约的总数，余号数量
        for (int i = 0; i < calendarResponseDtoList.size(); i++) {
            // 2. 通过 get(i) 获取元素
            CalendarResponseDto cd = calendarResponseDtoList.get(i);
            // 3. 防御性检查：跳过 null 元素（解决空指针问题）
            if (cd == null) {
                continue;
            }
            try {
                calendar.setTime(sdf.parse(cd.getYmd()));
            } catch (ParseException e) {
                e.printStackTrace();
            }
            int total = Integer.parseInt(ruleArr[calendar.get(Calendar.DAY_OF_WEEK) - 1]);
            cd.setTotal(total);
            cd.setRemainder(total - cd.getExisting());
        }
        return calendarResponseDtoList;
    }

}

